package lib

import (
	"fmt"
	"os"

	"github.com/cihub/seelog"
	serf "github.com/hashicorp/serf/client"

	"kyland.com/eagle/lib/config"
	. "kyland.com/eagle/lib/exception"
	"kyland.com/eagle/lib/node"
)

const (
	FILEEVENT   = "file"
	DEPLOYEVENT = "deploy"
)

type SerfClient struct {
	Client *serf.RPCClient
}

var (
	Client *SerfClient
)

func New() (*SerfClient, error) {
	serfConfig, err := config.Config.Get("serf")
	if err != nil {
		seelog.Error("create serf client error: %v", err)
		return nil, err
	}
	port := serfConfig.UString("port")
	ip := os.Getenv("NODE_IP")
	addr := fmt.Sprintf("%s:%s", ip, port)
	//seelog.Infof("get node addr: %s", addr)
	client, err := serf.NewRPCClient(addr)
	if err != nil {
		seelog.Error("create serf client error: %v", err)
		return nil, err
	}

	Client = &SerfClient{client}
	return Client, nil
}

func (client *SerfClient) GetMembers() []serf.Member {
	nodes, err := client.Client.Members()
	if err != nil {
		seelog.Errorf("get nodes error: %v", err)
		Throw(err)
	}

	return nodes
}

func (client *SerfClient) Join(node *node.Node) error {
	resp, err := client.Client.Join([]string{node.Name + "/" + node.Addr}, false)
	if err != nil {
		seelog.Errorf("join node, port failed: %d, %s, %s", resp, node.Name, node.Addr)
		return err
	}
	seelog.Info("%s/%sjoin success", node.Name, node.Addr)
	return nil
}

func (client *SerfClient) Event(event, payload string) error {
	err := client.Client.UserEvent(event, []byte(payload), false)
	if err != nil {
		seelog.Errorf("send user event failed: %v", err)
		return err
	}
	return nil
}
